Ã000 ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ - ----------------------------------------------------------------------------- Â000 ÂÁÓÉà ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÂÁÓÉà ÒÏÍÈ ÒÏÍÈ - Á000 ----------------------------------------------------------------------------- 9000 ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÏÍÌ ÒÁÍ ÒÏÍÌ ÒÏÍÌ(* 8000 ----------------------------------------------------------------------------- 7000 6000 ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ - 5000 4000 ----------------------------------------------------------------------------- 3000 2000 ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ - 1000 ----------------------------------------------------------------------------- 0000 ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ÒÁÍ ----------------------------------------------------------------------------- *) ÉNTERNAL MEMORY DOES NOT RESPOND TO WRITE ACCESSES TO THESE AREAS. ÌEGEND: ËERNAL Å000-ÆÆÆÆ ËERNAL ÒÏÍ. ÉÏ/à Ä000-ÄÆÆÆ É/Ï ADDRESS SPACE OR ÃHARACTER GENERATOR ÒÏÍ, SELECTED BY -ÃÈÁÒÅÎ. ÉF THE ÃÈÁÒÅÎ BIT IS CLEAR, THE CHARACTER GENERATOR ÒÏÍ IS CHOSEN. ÉF IT IS SET, THE É/Ï CHIPS ARE ACCESSIBLE. ÉÏ/ÒÁÍ Ä000-ÄÆÆÆ É/Ï ADDRESS SPACE OR ÒÁÍ, SELECTED BY -ÃÈÁÒÅÎ. ÉF THE ÃÈÁÒÅÎ BIT IS CLEAR, THE CHARACTER GENERATOR ÒÏÍ IS CHOSEN. ÉF IT IS SET, THE INTERNAL ÒÁÍ IS ACCESSIBLE. É/Ï Ä000-ÄÆÆÆ É/Ï ADDRESS SPACE. ÔHE -ÃÈÁÒÅÎ LINE HAS NO EFFECT. ÂÁÓÉà Á000-ÂÆÆÆ ÂÁÓÉà ÒÏÍ. ÒÏÍÈ Á000-ÂÆÆÆ OR ÅXTERNAL ÒÏÍ WITH THE -ÒÏÍÈ LINE Å000-ÆÆÆÆ CONNECTED TO ITS -ÃÓ LINE. ÒÏÍÌ 8000-9ÆÆÆ ÅXTERNAL ÒÏÍ WITH THE -ÒÏÍÌ LINE CONNECTED TO ITS -ÃÓ LINE. ÒÁÍ VARIOUS RANGES ÃOMMODORE 64'S INTERNAL ÒÁÍ. - 1000-7ÆÆÆ AND ÏPEN ADDRESS SPACE. Á000-ÃÆÆÆ ÔHE ÃOMMODORE 64'S MEMORY CHIPS DO NOT DETECT ANY MEMORY ACCESSES TO THIS AREA EXCEPT THE ÖÉÃ-ÉÉ'S ÄÍÁ AND MEMORY REFRESHES. ÎÏÔÅ: ×HENEVER THE PROCESSOR TRIES TO WRITE TO ANY ÒÏÍ AREA (ËERNAL, ÂÁÓÉÃ, ÃÈÁÒÏÍ, ÒÏÍÌ, ÒÏÍÈ), THE DATA WILL GET "THROUGH THE ÒÏÍ" TO THE Ã64'S INTERNAL ÒÁÍ. ÆOR THIS REASON, YOU CAN EASILY COPY DATA FROM ÒÏÍ TO ÒÁÍ, WITHOUT ANY BANK SWITCHING. ÂUT IMPLEMENTING EXTERNAL MEMORY EXPANSIONS WITHOUT ÄÍÁ IS VERY HARD, AS YOU HAVE TO USE THE ÕLTIMAX MEMORY CONFIGURATION, OR THE DATA WILL BE WRITTEN BOTH TO INTERNAL AND EXTERNAL ÒÁÍ. ÈOWEVER, THIS IS NOT TRUE FOR THE ÕLTIMAX GAME CONFIGURATION. ÉN THAT MODE, THE INTERNAL ÒÁÍ IGNORES ALL MEMORY ACCESSES OUTSIDE THE AREA $0000-$0ÆÆÆ, UNLESS THEY ARE PERFORMED BY THE ÖÉÃ, AND YOU CAN WRITE TO EXTERNAL MEMORY AT $1000-$ÃÆÆÆ AND $Å000-$ÆÆÆÆ, IF ANY, WITHOUT CHANGING THE CONTENTS OF THE INTERNAL ÒÁÍ. _Á NOTE CONCERNING THE É/Ï AREA_ ÔHE É/Ï AREA IS DIVIDED AS FOLLOWS: ÁDDRESS RANGE ÏWNER ------------- ----- Ä000-Ä3ÆÆ ÍÏÓ 6567/6569 ÖÉÃ-ÉÉ ÖIDEO ÉNTERFACE ÃONTROLLER Ä400-Ä7ÆÆ ÍÏÓ 6581 ÓÉÄ ÓOUND ÉNTERFACE ÄEVICE Ä800-ÄÂÆÆ ÃOLOR ÒÁÍ (ONLY LOWER NYBBLES ARE CONNECTED) ÄÃ00-ÄÃÆÆ ÍÏÓ 6526 ÃÉÁ ÃOMPLEX ÉNTERFACE ÁDAPTER #1 ÄÄ00-ÄÄÆÆ ÍÏÓ 6526 ÃÉÁ ÃOMPLEX ÉNTERFACE ÁDAPTER #2 ÄÅ00-ÄÅÆÆ ÕSER EXPANSION #1 (-É/Ï1 ON ÅXPANSION ÐORT) ÄÆ00-ÄÆÆÆ ÕSER EXPANSION #2 (-É/Ï2 ON ÅXPANSION ÐORT) ÁS YOU CAN SEE, THE ADDRESS RANGES FOR THE CHIPS ARE MUCH LARGER THAN REQUIRED. ÂECAUSE OF THIS, YOU CAN ACCESS THE CHIPS THROUGH MULTIPLE MEMORY AREAS. ÔHE ÖÉÃ-ÉÉ APPEARS IN ITS WINDOW EVERY $40 ADDRESSES. ÆOR INSTANCE, THE ADDRESSES $Ä040 AND $Ä080 ARE BOTH MAPPED TO THE ÓPRITE 0 Ø CO-ORDINATE REGISTER. ÔHE ÓÉÄ HAS ONE REGISTER SELECTION LINE LESS, THUS IT APPEARS AT EVERY $20 BYTES. ÔHE ÃÉÁ CHIPS HAVE ONLY 16 REGISTERS, SO THERE ARE 16 COPIES OF EACH IN THEIR MEMORY AREA. ÈOWEVER, YOU SHOULD NOT USE OTHER ADDRESSES THAN THOSE SPECIFIED BY ÃOMMODORE. ÆOR INSTANCE, THE ÃOMMODORE 128 MAPPED ITS ADDITIONAL É/Ï CHIPS TO THIS SAME MEMORY AREA, AND THE ÓÉÄ RESPONDS ONLY TO THE ADDRESSES Ä400-Ä4ÆÆ, ALSO WHEN IN Ã64 MODE. ÁND THE ÃOMMODORE 65, WHICH UNFORTUNATELY DID NOT MAKE ITS WAY TO THE MARKET, COULD NARROW THE MEMORY WINDOW RESERVED FOR THE ÍÏÓ 6569/6567 ÖÉÃ-ÉÉ (OR ÃÓÇ 4567 ÖÉÃ-ÉÉÉ IN THAT MACHINE). _ÔHE VIDEO CHIP_ ÔHE ÍÏÓ 6567/6569 ÖÉÃ-ÉÉ ÖIDEO ÉNTERFACE ÃONTROLLER HAS ACCESS TO ONLY 16 KILOBYTES AT A TIME. ÔO ENABLE THE ÖÉÃ-ÉÉ TO ACCESS THE WHOLE 64 K MEMORY SPACE, THE MAIN MEMORY IS DIVIDED TO FOUR BANKS OF 16 K EACH. ÔHE LINES ÐÁ0 AND ÐÁ1 OF THE SECOND ÃÉÁ ARE THE INVERSE OF THE VIRTUAL ÖÉÃ-ÉÉ ADDRESS LINES ÖÁ14 AND ÖÁ15, RESPECTIVELY. ÔO SELECT A ÖÉÃ-ÉÉ BANK OTHER THAN THE DEFAULT, YOU MUST PROGRAM THE ÃÉÁ LINES TO OUTPUT THE DESIRED BIT PAIR. ÆOR INSTANCE, THE FOLLOWING CODE SELECTS THE MEMORY AREA $4000-$7ÆÆÆ (BANK 1) FOR THE VIDEO CONTROLLER: ÌÄÁ $ÄÄ02 ; ÄATA ÄIRECTION ÒEGISTER Á ÏÒÁ #$03 ; ÓET PINS ÐÁ0 AND ÐÁ1 TO OUTPUTS ÓÔÁ $ÄÄ02 ÌÄÁ $ÄÄ00 ÁÎÄ #$Æà ; ÍASK THE LOWMOST BIT PAIR OFF ÏÒÁ #$02 ; ÓELECT ÖÉÃ-ÉÉ BANK 1 (THE INVERSE OF BINARY 01 IS 10) ÓÔÁ $ÄÄ00 ×HY SHOULD YOU SET THE PINS TO OUTPUTS? ÈARDWARE ÒÅÓÅÔ RESETS ALL É/Ï LINES TO INPUTS, AND THANKS TO THE ÃÉÁ'S INTERNAL PULL-UP RESISTORS, THE INPUTS ACTUALLY OUTPUT LOGICAL HIGH VOLTAGE LEVEL. ÓO, UPON -ÒÅÓÅÔ, THE VIDEO BANK 0 IS SELECTED AUTOMATICALLY, AND OLDER ËERNALS COULD LEAVE IT UNINITIALIZED. ÎOTE THAT THE ÖÉÃ-ÉÉ ALWAYS FETCHES ITS INFORMATION FROM THE INTERNAL ÒÁÍ, TOTALLY IGNORING THE MEMORY CONFIGURATION LINES. ÔHERE IS ONLY ONE EXCEPTION TO THIS RULE: ÔHE CHARACTER GENERATOR ÒÏÍ. ÕNLESS THE ÕLTIMAX MODE IS SELECTED, ÖÉÃ-ÉÉ "SEES" CHARACTER GENERATOR ÒÏÍ IN THE MEMORY AREAS 1000-1ÆÆÆ AND 9000-9ÆÆÆ. ÉF THE ÕLTIMAX CONFIGURATION IS ACTIVE, THE ÖÉÃ-ÉÉ WILL FETCH ALL DATA FROM THE INTERNAL ÒÁÍ. _ÁN APPLICATION: ÍAKING AN OPERATING SYSTEM EXTENSION_ ÉF YOU ARE MAKING A MEMORY RESIDENT PROGRAM AND WANT TO MAKE IT AS INVISIBLE TO THE SYSTEM AS POSSIBLE, PROBABLY THE BEST METHOD IS KEEPING MOST OF YOUR CODE UNDER THE É/Ï AREA (IN THE ÒÁÍ AT $Ä000-$ÄÆÆÆ). ÔHIS AREA IS VERY SAFE, SINCE PROGRAMS UTILIZING IT ARE RARE, SINCE THEY ARE VERY DIFFICULT TO IMPLEMENT AND TO DEBUG. ÙOU NEED ONLY A SHORT ROUTINE IN THE NORMALLY VISIBLE ÒÁÍ THAT PUSHES THE CURRENT VALUE OF THE PROCESSOR'S É/Ï REGISTER $01 ON STACK, SWITCHES ÒÁÍ ON TO $Ä000-$ÄÆÆÆ AND JUMPS TO THIS AREA. ÒETURNING FROM THE $Ä000-$ÄÆÆÆ AREA IS POSSIBLE EVEN WITHOUT ANY ROUTINE IN THE NORMALLY VISIBLE ÒÁÍ AREA. ÊUST WRITE AN ÒÔÓ OR AN ÒÔÉ TO AN É/Ï REGISTER AND RETURN THROUGH IT. ÂUT WHAT IF YOUR PROGRAM NEEDS TO USE É/Ï? ÁND HOW CAN YOU WRITE THE RETURN INSTRUCTION TO AN É/Ï REGISTER WHILE THE É/Ï AREA IS SWITCHED OFF? ÙOU NEED A SWAP AREA FOR YOUR PROGRAM IN NORMALLY VISIBLE MEMORY. ÔHE FIRST THING YOUR ROUTINE AT $Ä000-$ÄÆÆÆ DOES IS COPYING THE É/Ï ROUTINES (OR THE WHOLE PROGRAM) TO NORMALLY VISIBLE MEMORY, SWAPPING THE BYTES. ÆOR INSTANCE, IF YOUR É/Ï ROUTINES ARE INITIALLY BEING STORED AT $Ä200-$Ä3ÆÆ, EXCHANGE THE BYTES IN $Ä200-$Ä3ÆÆ WITH THE CONTENTS OF $Ã000-$Ã1ÆÆ. ÎOW YOU CAN CALL THE É/Ï ROUTINES FROM YOUR ROUTINE AT $Ä000-$ÄÆÆÆ, AND THE É/Ï ROUTINES CAN SWITCH THE É/Ï AREA TEMPORARILY ON TO ACCESS THE É/Ï CHIPS. ÁND RIGHT BEFORE EXITING YOUR PROGRAM AT $Ä000-$ÄÆÆÆ SWAPS THE OLD CONTENTS OF THAT É/Ï ROUTINE AREA IN, E.G. EXCHANGES THE MEMORY AREAS $Ä200-$Ä3ÆÆ AND $Ã000-$Ã1ÆÆ AGAIN. ×HAT É/Ï REGISTERS CAN YOU USE FOR THE RETURN INSTRUCTION? ÔHERE ARE BASICALLY TWO ALTERNATIVES: 8-BIT ÖÉà SPRITE REGISTERS OR EITHER ÃÉÁ'S SERIAL PORT REGISTER. ÔHE ÖÉà REGISTERS ARE EASIEST TO USE, AS THEY ACT PRECISELY LIKE MEMORY PLACES: YOU CAN EASILY WRITE THE DESIRED VALUE TO A REGISTER. ÂUT THE ÃÉÁ REGISTER IS USUALLY BETTER, AS CHANGING THE ÖÉà REGISTERS MIGHT CHANGE THE SCREEN LAYOUT. ÈOWEVER, ALSO THE ÓÐ REGISTER HAS SOME DRAWBACKS: ÉF THE MACHINE'S ÃÎÔ1 AND ÃÎÔ2 LINES ARE CONNECTED TO A FREQUENCY SOURCE, YOU MUST STOP EITHER ÃÉÁ'S ÔIMER Á TO USE THE ÓÐ REGISTER METHOD. ÎORMALLY THE 1ST ÃÉÁ'S ÔIMER Á IS THE MAIN HARDWARE INTERRUPT SOURCE. ÁND IF YOU USE THE ËERNAL'S ÒÓ232, YOU CANNOT STOP THE 2ND ÃÉÁ'S ÔIMER Á EITHER. ÁLSO, IF YOU DON'T WANT TO LOSE ANY ÃÉÁ INTERRUPTS, YOU MIGHT WANT TO KNOW THAT EXECUTING THE ÒÔÓ OR ÒÔÉ AT ÓÐ REGISTER HAS THE SIDE EFFECT OF READING THE ÉNTERRUPT ÃONTROL ÒEGISTER, THUS ACKNOWLEDGING AN INTERRUPT THAT MIGHT HAVE BEEN WAITING. ÉF YOU CAN'T USE EITHER METHOD, YOU CAN USE EITHER ÃÉÁ'S ÔOÄ SECONDS OR MINUTES OR ÔOÄ ALARM TIME FOR STORING AN ÒÔÉ. ÏR, IF YOU DON'T WANT TO ALTER ANY REGISTERS, USE THE ÖÉÃ-ÉÉ'S LIGHT PEN REGISTER. ÂEFORE EXITING, WAIT FOR APPROPRIATE RASTER LINE AND TRIG THE LIGHT PEN LATCH WITH ÃÉÁ1'S ÐÂ4 BIT. ÈOWEVER, THIS METHOD ASSUMES THAT THE CONTROL PORT 1'S BUTTON/LIGHT PEN LINE REMAINS UP FOR THAT FRAME. ÁFTER TRIGGING THE LIGHT PEN, CAUSING THE LIGHT PEN Ù CO-ORDINATE REGISTER ($Ä014) TO BE $40 OR $60, YOU HAVE MORE THAN HALF A FRAME TIME TO RESTORE THE STATE OF THE É/Ï CHIPS AND RETURN THROUGH THE REGISTER. ÙOU CAN ALSO USE THE ÓÉÄ TO STORE AN ÒÔÉ OR ÒÔÓ COMMAND. ÈOW IS THIS POSSIBLE, YOU MIGHT ASK. ÁFTER ALL, THE CHIP CONSISTS OF READ ONLY OR WRITE ONLY REGISTERS. ÈOWEVER, THERE ARE TWO REGISTERS THAT CAN BE CONTROLLED BY PROGRAM, THE ENVELOPE GENERATOR AND OSCILLATOR OUTPUTS OF THE THIRD VOICE. ÔHIS METHOD REQUIRES YOU TO CHANGE THE FREQUENCY OF VOICE 3 AND TO SELECT A WAVEFORM FOR IT. ÔHIS WILL AFFECT ON THE VOICE OUTPUT BY TURNING THE VOICE 3 OFF, BUT WHO WOULD KEEP THE VOICE 3 PRODUCING A TONE WHILE CALLING AN OPERATING SYSTEM ROUTINE? ÁLSO KEEP IN MIND THAT THE USER COULD PRESS ÒÅÓÔÏÒÅ WHILE THE ËERNAL ÒÏÍ AND É/Ï AREAS ARE DISABLED. ÙOU COULD WRITE YOUR OWN NON-MASKABLE INTERRUPT (ÎÍÉ) HANDLER (USING THE ÎÍÉ VECTOR AT $ÆÆÆÁ), BUT A FAST LOADER THAT USES VERY TIGHT TIMING WOULD STILL STOP WORKING IF THE USER PRESSED ÒÅÓÔÏÒÅ IN THE MIDDLE OF A DATA BLOCK TRANSFER. ÓO, TO MAKE A ROBUST PROGRAM, YOU HAVE TO DISABLE ÎÍÉ INTERRUPTS. ÂUT HOW IS THIS POSSIBLE? ÔHEY ARE ÎON-ÍASKABLE AFTER ALL. ÔHE ÎÍÉ INTERRUPT IS EDGE-SENSITIVE, THE PROCESSOR JUMPS TO ÎÍÉ HANDLER ONLY WHEN THE -ÎÍÉ LINE DROPS FROM +5Ö TO GROUND. ÔO DISABLE THE INTERRUPT, SIMPLY CAUSE AN ÎÍÉ WITH ÃÉÁ2'S TIMER, BUT DON'T READ THE ÉNTERRUPT ÃONTROL REGISTER. ÉF YOU NEED TO READ $ÄÄ0Ä IN YOUR PROGRAM, YOU MUST ADD A ÎÍÉ HANDLER JUST IN CASE THE USER PRESSES ÒÅÓÔÏÒÅ. ÁND DON'T FORGET TO RAISE THE -ÎÍÉ LINE UPON EXITING THE PROGRAM. ÏTHERWISE THE ÒÅÓÔÏÒÅ KEY DOES NOT WORK UNTIL THE USER ISSUES A -ÒÅÓÅÔ OR READS THE ÉÃÒ REGISTER EXPLICITLY. (ÔHE ËERNAL DOES NOT READ $ÄÄ0Ä, UNLESS IT IS HANDLING AN INTERRUPT.) ÔHIS CAN BE DONE AUTOMATICALLY BY THE TWO FOLLOWING ÓÐ REGISTER EXAMPLES DUE TO ONE OF THE 6510'S UNDOCUMENTED FEATURES (REFER TO THE DESCRIPTIONS OF ÒÔÓ AND ÒÔÉ BELOW). ; ÒETURNING VIA ÖÉà SPRITE 7 Ø CO-ORDINATE REGISTER ÉNITIALIZATION: ; ÔHIS IS EXECUTED WHEN É/Ï IS SWITCHED ON ÌÄÁ #$60 ÓÔÁ $Ä015 ; ×RITE ÒÔÓ TO ÖÉà REGISTER $15. ÅXITING: ; ÎÏÔÅ: ÔHIS PROCEDURE MUST START AT ÖÉà REGISTER ; $12. ÙOU HAVE MULTIPLE ALTERNATIVES, AS THE ÖÉà ; APPEARS IN MEMORY AT $Ä000+$40*N, WHERE $0<=N<=$Æ. ÐÌÁ ; ÐULL THE SAVED 6510 É/Ï REGISTER STATE FROM STACK ÓÔÁ $01 ; ÒESTORE ORIGINAL MEMORY BANK CONFIGURATION ; ÎOW THE PROCESSOR FETCHES THE ÒÔÓ COMMAND FROM THE ; ÖÉà REGISTER $15. ; ÒETURNING VIA ÃÉÁ 2'S ÔOÄ OR ÔOÄ ALARM SECONDS REGISTER ÉNITIALIZATION: ; ÔHIS IS EXECUTED WHEN É/Ï IS SWITCHED ON ÌÄÁ #$40 ÓÔÁ $ÄÄ08 ; ÓET ÔOÄ TENTHS OF SECONDS ; (CLEAR IT SO THAT THE SECONDS REGISTER ; WOULD NOT OVERFLOW) ; ÉF ÔOÄ ALARM REGISTER IS SELECTED, THIS ; INSTRUCTION WILL BE UNNECESSARY. ÓÔÁ $ÄÄ09 ; ÓET ÔOÄ SECONDS ÌÄÁ $ÄÄ0 ; ÒEAD ÔOÄ HOURS (FREEZE ÔOÄ DISPLAY) ÅXITING: ; ÎÏÔÅ: ÔHIS PROCEDURE MUST START AT ÃÉÁ 2 REGISTER ; $6. ÁS THE ÃÉÁ 2 APPEARS IN MEMORY AT $ÄÄ00+$10*N, ; WHERE 0<=N<=$Æ, YOU HAVE SIXTEEN ALTERNATIVES. ÐÌÁ ÓÔÁ $01 ; ÒESTORE ORIGINAL MEMORY BANK CONFIGURATION ; ÎOW THE PROCESSOR FETCHES THE ÒÔÓ COMMAND FROM ; THE ÃÉÁ 2 REGISTER $9. ; ÒETURNING VIA ÃÉÁ 2'S ÓÐ REGISTER (ASSUMING THAT ÃÎÔ2 IS STABLE) ÉNITIALIZATION: ; ÔHIS IS EXECUTED WHEN É/Ï IS SWITCHED ON ÌÄÁ $ÄÄ0Å ; ÃÉÁ 2'S ÃONTROL ÒEGISTER Á ÁÎÄ #$ÂÆ ; ÓET ÓERIAL ÐORT TO INPUT ÓÔÁ $ÄÄ0Å ; (MAKE THE ÓÐ REGISTER TO ACT AS A MEMORY PLACE) ÌÄÁ #$60 ÓÔÁ $ÄÄ0à ; ×RITE ÒÔÓ TO ÃÉÁ 2 REGISTER $Ã. ÅXITING: ; ÎÏÔÅ: ÔHIS PROCEDURE MUST START AT ÃÉÁ 2 REGISTER ; $9. ÁS THE ÃÉÁ 2 APPEARS IN MEMORY AT $ÄÄ00+$10*N, ; WHERE 0<=N<=$Æ, YOU HAVE SIXTEEN ALTERNATIVES. ÐÌÁ ÓÔÁ $01 ; ÒESTORE ORIGINAL MEMORY BANK CONFIGURATION ; ÎOW THE PROCESSOR FETCHES THE ÒÔÓ COMMAND FROM ; THE ÃÉÁ 2 REGISTER $Ã. ; ÒETURNING VIA ÃÉÁ 2'S ÓÐ REGISTER, STOPPING THE ÔIMER Á ; AND FORCING ÓÐ2 AND ÃÎÔ2 TO OUTPUT ÉNITIALIZATION: ; ÔHIS IS EXECUTED WHEN É/Ï IS SWITCHED ON ÌÄÁ $ÄÄ0Å ; ÃÉÁ 2'S ÃONTROL ÒEGISTER Á ÁÎÄ #$ÆÅ ; ÓTOP ÔIMER Á ÏÒÁ #$40 ; ÓET ÓERIAL ÐORT TO OUTPUT ÓÔÁ $ÄÄ0Å ; (MAKE THE ÓÐ REGISTER TO ACT AS A MEMORY PLACE) ÌÄÁ #$60 ÓÔÁ $ÄÄ0à ; ×RITE ÒÔÓ TO ÃÉÁ REGISTER $Ã. ÅXITING: ; ÎÏÔÅ: ÔHIS PROCEDURE MUST START AT ÃÉÁ 2 REGISTER ; $9. ÁS THE ÃÉÁ 2 APPEARS IN MEMORY AT $ÄÄ00+$10*N, ; WHERE 0<=N<=$Æ, YOU HAVE SIXTEEN ALTERNATIVES. ÐÌÁ ÓÔÁ $01 ; ÒESTORE ORIGINAL MEMORY BANK CONFIGURATION ; ÎOW THE PROCESSOR FETCHES THE ÒÔÓ COMMAND FROM ; THE ÃÉÁ 2 REGISTER $Ã. ; ÒETURNING VIA ÓÉÄ OSCILLATOR 3 OUTPUT REGISTER ÉNITIALIZATION: ; ÔHIS IS EXECUTED WHEN É/Ï IS SWITCHED ON ÌÄÁ #$20 ; ÓELECT SAWTOOTH WAVEFORM ÓÔÁ $Ä412 ; BUT DO NOT ENABLE THE SOUND ÌÄÙ #$00 ; ÓELECT FREQUENCY ÓÔÙ $Ä40Å ; (SYSTEM CLOCK)/$ÆÆ00, ÌÄÁ #$ÆÆ ; CAUSING THE ÏÓÃ3 OUTPUT TO INCREMENT BY ONE ÓÔÙ $Ä40Æ ; EVERY $10000/$ÆÆ00 CYCLES. ÌÄÁ #$0Å ÌÄØ #$60 ÂÉÔ $Ä41 ; ×AIT FOR THE OSCILLATOR 3 OUTPUT ÂÍÉ *-3 ; TO BE IN THE RANGE ÂÖÓ *-5 ; $00-$3Æ. ÂÉÔ $Ä41 ; ×AIT FOR THE OSCILLATOR 3 OUTPUT ÂÖà *-3 ; TO BE AT LEAST $40. ÓÔÁ $Ä40Æ ; ÓLOW DOWN THE FREQUENCY TO (SYSTEM CLOCK)/$0Å00. ÃÐØ $Ä41 ; ×AIT FOR THE OSCILLATOR 3 ÂÎÅ *-3 ; OUTPUT TO REACH $60 (ÒÔÓ) ÓÔÙ $Ä40Æ ; ÒESET THE FREQUENCY OF VOICE 3 ; (STOP THE ÏÓÃ3 REGISTER FROM INCREASING) ÅXITING: ; ÎÏÔÅ: ÔHIS PROCEDURE MUST START AT ÓÉÄ REGISTER ; $18. ÁS THE ÓÉÄ APPEARS IN MEMORY AT $Ä400+$20*N, ; WHERE 0<=N<=$20, YOU HAVE THIRTY-TWO ALTERNATIVES. ; ÈOWEVER, IN Ã128 THERE ARE ONLY EIGHT ALTERNATIVES, ; AS THE ÓÉÄ IS ONLY AT $Ä400-$Ä4ÆÆ. ÐÌÁ ÓÔÁ $01 ; ÒESTORE ORIGINAL MEMORY BANK CONFIGURATION ; ÎOW THE PROCESSOR FETCHES THE ÒÔÓ COMMAND FROM ; THE ÓÉÄ REGISTER $1Â. ÆOR INSTANCE, IF YOU WANT TO MAKE A HIGHLY COMPATIBLE FAST LOADER, MAKE THE ÉÌÏÁÄ VECTOR ($0330) POINT TO THE BEGINNING OF THE STACK AREA. ÒEMEMBER THAT THE ÂÁÓÉà INTERPRETER USES THE FIRST BYTES OF STACK WHILE CONVERTING NUMBERS TO TEXT. Á GOOD ADDRESS IS $0120. ÒOBUST PROGRAMS PRACTICALLY NEVER USE SO MUCH STACK THAT IT COULD CORRUPT THIS ROUTINE. ÕSUALLY ONLY CRUNCHED PROGRAMS (DEMOS AND ALIKE) USE ALL STACK IN THE DECOMPRESSION PHASE. ÔHEY ALSO MAKE USE OF THE $Ä000-$ÄÆÆÆ AREA. ÔHIS STACK ROUTINE WILL JUMP TO YOUR ROUTINE AT $Ä000-$ÄÆÆÆ, AS DESCRIBED ABOVE. ÆOR PERFORMANCE'S SAKE, COPY THE WHOLE BYTE TRANSFER LOOP TO THE SWAP AREA, E.G. $Ã000-$Ã1ÆÆ, AND CALL THAT SUBROUTINE AFTER DOING THE PRELIMINARY WORK. ÂUT WHAT ABOUT FILES THAT LOAD OVER $Ã000-$Ã1ÆÆ? ×OULDN'T THAT DESTROY THE TRANSFER LOOP AND JAM THE MACHINE? ÎOT NECESSARILY. ÉF YOU COPY THOSE BYTES TO YOUR SWAP AREA AT $Ä000-$ÄÆÆÆ, THEY WILL BE LOADED PROPERLY, AS YOUR PROGRAM RESTORES THE ORIGINAL $Ã000-$Ã1ÆÆ AREA. ÉF YOU WANT TO MAKE YOUR PROGRAM USER-FRIENDLY, PUT A VECTOR INITIALIZATION ROUTINE TO THE STACK AREA AS WELL, SO THAT THE USER CAN RESTORE THE FAST LOADER BY ISSUING A ÓÙÓ COMMAND, RATHER THAN LOADING IT EACH TIME HE HAS PRESSED ÒÅÓÅÔ. _ÁN EXAMPLE: Á "HELLO WORLD" PROGRAM_ ÔO HELP YOU IN GETTING STARTED, É HAVE WRITTEN A SMALL EXAMPLE PROGRAM THAT ECHOES THE FAMOUS MESSAGE "HELLO, WORLD!" TO STANDARD OUTPUT (NORMALLY SCREEN) USING THE ËERNAL'S ÃÈÒÏÕÔ SUBROUTINE. ÁFTER THE INITIALIZATION ROUTINE HAS BEEN RUN, THE PROGRAM CAN BE STARTED BY COMMANDING ÓÙÓ 300. É USED THE ÃOMMODORE 128'S MACHINE LANGUAGE MONITOR TO PUT IT UP, BUT IT WAS STILL PRETTY DIFFICULT TO DEBUG THE PROGRAM. ÈERE IT IS IN UUENCODED FORMAT: BEGIN 644 HELLO ÍÀ0@+",Ä'ÇÃ(Ð-Ã$ÀÀÀ!ØÉ0%(*?Â%À:(,Ï3À(Ç2Ð!ÒÁ#×ÈÈÎ]/ÀÂ=8]×*Ô/=È ÍÁ0%88*4!ÊÂÇØ"01ØÁ0%,É-×ÆÀ:*!Ã@×=È@".!=×ÈÃ@3=ÈÍÖ.#ÍÖÂ0(Ø,×<8! Í8*4!2ÀÄ#Á0&@#+ÄÓÐ"#2_Ø@0]ÖÂ%À6ÀÁ1$Ñ23Õ<@+$],3$5(ÂÄÂÍ^Ï](Ë?Ï_ Í2*Ä6Ã?Ë_Ê<"-^_\@×-Ô@À,!ÈÃ?Ï_:(×Ú_ÒÀ=Ð"#<×6ÂÈÊ0!(ÎÏØ"À=À#_@,! 5ÁÀ&@/[ØÀÐ+ÅÄ×9ÄÀÐ(Ê99-Ö($/!@ À END ÉN ORDER TO FULLY UNDERSTAND THE OPERATION OF THIS PROGRAM, YOU NEED TO KNOW HOW THE INSTRUCTIONS ÒÔÉ, ÒÔÓ AND ÐÈÁ WORK. ÔHERE IS SOME WORK GOING ON TO REVERSE ENGINEER THE ÎÍÏÓ 6502 MICROPROCESSOR TO LARGE EXTENT, AND IT IS NOW KNOWN FOR MOST INSTRUCTIONS WHAT MEMORY PLACES THEY ACCESS DURING THEIR EXECUTION AND FOR WHAT PURPOSE. ÔHE INTERNAL PROCEDURES HAVEN'T BEEN DESCRIBED IN DETAIL YET, BUT THESE DESCRIPTIONS SHOULD BE EASIER TO READ ANYWAY. ÆOR CURIOSITY, É QUOTE HERE THE DESCRIPTION OF ALL INSTRUCTIONS THAT USE THE STACK. ÔHE DESCRIPTIONS OF INTERNAL OPERATIONS ARE YET INACCURATE, BUT THE MEMORY ACCESSES HAVE BEEN VERIFIED WITH AN OSCILLOSCOPE. É WILL MAIL COPIES THE WHOLE DOCUMENT UPON REQUEST. ×HEN FINISHED, THE DOCUMENT WILL BE PUT ON AN ÆÔÐ SITE. ÊÓÒ # ADDRESS Ò/× DESCRIPTION --- ------- --- ------------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò FETCH ADDRESS'S LOW BYTE TO LATCH, INCREMENT Ðà 3 $0100,Ó Ò 4 $0100,Ó × PUSH ÐÃÈ ON STACK, DECREMENT Ó 5 $0100,Ó × PUSH ÐÃÌ ON STACK, DECREMENT Ó 6 ÐÃ Ò COPY LATCH TO ÐÃÌ, FETCH ADDRESS'S HIGH BYTE TO LATCH, COPY LATCH TO ÐÃÈ ÒÔÓ # ADDRESS Ò/× DESCRIPTION --- ------- --- ----------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY), INCREMENT Ðà 3 $0100,Ó Ò INCREMENT Ó 4 $0100,Ó Ò PULL ÐÃÌ FROM STACK, INCREMENT Ó 5 $0100,Ó Ò PULL ÐÃÈ FROM STACK 6 ÐÃ Ò INCREMENT Ðà ÂÒË # ADDRESS Ò/× DESCRIPTION --- ------- --- ----------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY), INCREMENT Ðà 3 $0100,Ó × PUSH ÐÃÈ ON STACK, DECREMENT Ó 4 $0100,Ó × PUSH ÐÃÌ ON STACK, DECREMENT Ó 5 $0100,Ó × PUSH Ð ON STACK (WITH  FLAG SET), DECREMENT Ó, SET É FLAG 6 $ÆÆÆÅ Ò FETCH ÐÃÌ 7 $ÆÆÆÆ Ò FETCH ÐÃÈ ÒÔÉ # ADDRESS Ò/× DESCRIPTION --- ------- --- ----------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY), INCREMENT Ðà 3 $0100,Ó Ò INCREMENT Ó 4 $0100,Ó Ò PULL Ð FROM STACK, INCREMENT Ó 5 $0100,Ó Ò PULL ÐÃÌ FROM STACK, INCREMENT Ó 6 $0100,Ó Ò PULL ÐÃÈ FROM STACK ÐÈÁ, ÐÈÐ # ADDRESS Ò/× DESCRIPTION --- ------- --- ----------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY), INCREMENT Ðà 3 $0100,Ó × PUSH REGISTER ON STACK, DECREMENT Ó ÐÌÁ, ÐÌÐ # ADDRESS Ò/× DESCRIPTION --- ------- --- ----------------------------------------------- 1 ÐÃ Ò FETCH OPCODE, INCREMENT Ðà 2 ÐÃ Ò READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY), INCREMENT Ðà 3 $0100,Ó Ò INCREMENT Ó 4 $0100,Ó Ò PULL REGISTER FROM STACK ÔHE EXAMPLE PROGRAM CONSISTS OF THREE PARTS. ÔHE FIRST PART TRANSFERS THE OTHER PARTS TO APPROPRIATE MEMORY AREAS. ÔHE SECOND PART IS LOCATED IN STACK AREA (300-312), AND IT INVOKES THE THIRD PART, THE MAIN MODULE. ÔHE LOADER PART ($0801-$08Ã7) IS AS FOLLOWS: 1993 ÓÙÓ2061 080Ä ÓÅÉ ÄISABLE INTERRUPTS. 080Å ÌÄÁ $01 0810 ÐÈÁ ÓTORE THE STATE OF THE PROCESSOR'S É/Ï LINES. 0811 ÁÎÄ #$Æ8 0813 ÓÔÁ $01 ÓELECT 64 K ÒÁÍ MEMORY CONFIGURATION. 0815 ÌÄØ #$0à ÃOPY THE INVOKING PART TO 300-312. 0817 ÌÄÁ $0830,Ø 081Á ÓÔÁ $012Ã,Ø 081Ä ÄÅØ 081Å ÂÐÌ $0817 0820 ÌÄØ #$8 ÃOPY THE MAIN PART TO $ÄÄ64-$ÄÄÅÅ. 0822 ÌÄÁ $083Ã,Ø 0825 ÓÔÁ $ÄÄ63,Ø 0828 ÄÅØ 0829 ÂÎÅ $0822 082 ÐÌÁ ÒESTORE ORIGINAL MEMORY CONFIGURATION. 082à ÓÔÁ $01 082Å ÃÌÉ ÅNABLE INTERRUPTS. 082Æ ÒÔÓ ÒETURN. ÔHE USER INVOKES THE FOLLOWING PART BY ISSUING ÓÙÓ 300. ÔHIS PART CHANGES THE MEMORY CONFIGURATION AND JUMPS TO THE MAIN PART. 012à ÌÄÁ $01 012Å ÔÁØ ÓTORE ORIGINAL MEMORY CONFIGURATION TO Ø REGISTER. 012Æ ÁÎÄ #$Æ8 0131 ÏÒÁ #$04 0133 ÓÅÉ ÄISABLE INTERRUPTS. 0134 ÓÔÁ $01 ÓELECT 64 K ÒÁÍ MEMORY CONFIGURATION. 0136 ÊÍÐ $ÄÄÁ4 ÊUMP TO THE MAIN PART. ÔHE MAIN PART ACTUALLY CONSISTS OF TWO PARTS. ÉT MAY BE A BIT COMPLICATED, AND IT MIGHT TEACH NEW TRICKS TO YOU. ÄÄÁ4 ÔØÁ ÄÄÁ5 ÐÈÁ ÐUSH ORIGINAL MEMORY CONFIGURATION ON STACK. ÄÄÁ6 ÌÄÁ $ÆÆÆÁ ÄÄÁ9 ÐÈÁ ÄÄÁÁ ÌÄÁ $ÆÆÆ ÄÄÁÄ ÐÈÁ ÓTORE THE ORIGINAL VALUES OF $ÆÆÆÁ AND $ÆÆÆÂ. ÄÄÁÅ ÌÄÁ #$16 ÄÄÂ0 ÓÔÁ $ÆÆÆÁ ÓET ($ÆÆÆÁ) TO POINT TO ÒÔÉ. ÄÄÂ3 ÌÄÁ #$Ã0 ÄÄÂ5 ÓÔÁ $ÆÆÆ ÄÄÂ8 ÊÓÒ $ÄÄÄà ÓWAP THE AUXILIARY ROUTINES IN. ÄÄ ÊÓÒ $Ã000 ÄISABLE ÎÍÉ'S AND INITIALIZE ÃÉÁ2. ÄÄÂÅ ÐÌÁ ÄÄÂÆ ÓÔÁ $ÆÆÆ ÒESTORE ORIGINAL VALUES TO $ÆÆÆÁ AND $ÆÆÆÂ. ÄÄÃ2 ÐÌÁ ÄÄÃ3 ÓÔÁ $ÆÆÆÁ ÄÄÃ6 ÊÓÒ $Ã01Ä ÐRINT THE MESSAGE. ÄÄÃ9 ÊÓÒ $ÄÄÄà ÓWAP THE AUXILIARY ROUTINES OUT. ÄÄÃà ÐÌÁ ÄÄÃÄ ÔÁÙ ÌOAD ORIGINAL MEMORY CONFIGURATION TO Ù REGISTER. ÄÄÃÅ ÌÄÁ #$00 ÐUSH DESIRED STACK REGISTER VALUE ON STACK ÄÄÄ0 ÐÈÁ (CLEAR ALL FLAGS, ESPECIALLY THE É FLAG). ÄÄÄ1 ÔÓØ ÄÄÄ2 ÉÎà $0102,Ø ÉNCREMENT THE RETURN ADDRESS. ÄÄÄ5 ÂÎÅ $ÄÄÄÁ (ÒÔÓ PREINCREMENTS IT, BUT ÒÔÉ DOES NOT.) ÄÄÄ7 ÉÎà $0103,Ø ÄÄÄÁ ÓÔÙ $01 ÒESTORE ORIGINAL MEMORY CONFIGURATION. (ÔHE 6510 FETCHES THE NEXT INSTRUCTION FROM $ÄÄÄÃ, WHICH IS NOW CONNECTED TO THE ÃÉÁ2'S REGISTER $Ã, THE ÓERIAL ÐORT REGISTER. ÔHE INITIALIZATION ROUTINE WROTE AN ÒÔÉ TO IT. ÔHE PROCESSOR ALSO READS FROM $ÄÄÄÄ AS A SIDE EFFECT OF THE INSTRUCTION FETCH, THUS RE-ENABLING ÎÍÉ'S.) ÄÄÄà ÌÄÙ #$3Æ ÓUBROUTINE: ÓWAP THE MEMORY AREAS $Ã000-$Ã03Æ ÄÄÄÅ ÌÄØ $Ã000,Ù AND $ÄÄ64-$ÄÄÁ3 WITH EACH OTHER. ÄÄÅ1 ÌÄÁ $ÄÄ64,Ù ÄÄÅ4 ÓÔÁ $Ã000,Ù ÄÄÅ7 ÔØÁ ÄÄÅ8 ÓÔÁ $ÄÄ64,Ù ÄÄÅ ÄÅÙ ÄÄÅà ÂÐÌ $ÄÄÄÅ ÄÄÅÅ ÒÔÓ Ã000 ÉÎà $01 ÅNABLE THE É/Ï AREA. Ã002 ÌÄØ #$81 Ã004 ÓÔØ $ÄÄ0Ä ÅNABLE ÔIMER Á INTERRUPTS OF ÃÉÁ2. Ã007 ÌÄØ #$00 Ã009 ÓÔØ $ÄÄ05 Ã00à ÉÎØ Ã00Ä ÓÔØ $ÄÄ04 ÐREPARE ÔIMER Á TO COUNT FROM 1 TO 0. Ã010 ÌÄØ #$ÄÄ Ã012 ÓÔØ $ÄÄ0Å ÃAUSE AN INTERRUPT. (ÔHE INSTRUCTION SETS ÓÐ TO OUTPUT, MAKES ÔIMER Á TO COUNT SYSTEM CLOCK PULSES, FORCES THE ÃÉÁ TO LOAD THE INITIAL VALUE TO THE COUNTER, SELECTS ONE-SHOT COUNTING AND STARTS THE TIMER.) Ã015 ÌÄØ #$40 (ÔHE PROCESSOR NOW JUMPS TO THE ÎÍÉ HANDLER ($Ã016), AND THE ÓÐ REGISTER STARTS TO ACT AS A MEMORY PLACE.) Ã017 ÓÔØ $ÄÄ0à ×RITE AN ÒÔÉ TO ÓERIAL ÐORT REGISTER. Ã01Á ÄÅà $01 ÄISABLE THE É/Ï AREA. Ã01à ÒÔÓ ÒETURN. Ã01Ä ÌÄÁ $01 Ã01Æ ÐÈÁ Ã020 ÏÒÁ #$03 ÅNABLE É/Ï AND ÒÏÍS. Ã022 ÓÔÁ $01 Ã024 ÌÄÙ #$0à ÐRINT THE MESSAGE. Ã026 ÌÄÁ $Ã033,Ù Ã029 ÊÓÒ $ÆÆÄ2 Ã02à ÄÅÙ Ã02Ä ÂÐÌ $Ã026 Ã02Æ ÐÌÁ Ã030 ÓÔÁ $01 ÒESTORE THE 64 K MEMORY CONFIGURATION. Ã032 ÒÔÓ Ã033 "!ÄÌÒÏ× ,ÏÌÌÅÈ" (ÔHE STRING IS BACKWARDS IN MEMORY, SINCE É DON'T WANT TO WASTE CYCLES IN EXPLICIT COMPARISONS. ÔHIS METHOD RESULTS IN MORE READABLE CODE THAN DOING A FORWARD LOOP WITH AN INDEX VALUE $100-(NUMBER OF CHARACTERS).) ÔHIS PROGRAM IS NOT EXCELLENT. ÉT HAS THE FOLLOWING BUGS: O ÔHE 6510'S MEMORY MANAGEMENT LINES Ð0 AND Ð1 (ÌÏÒÁÍ AND ÈÉÒÁÍ, RESPECTIVELY) ARE ASSUMED TO BE OUTPUTS. ÉF YOU ISSUED THE COMMAND ÐÏËÅ0,ÐÅÅË(0)ÁÎÄ252, THIS PROGRAM WOULD NOT WORK. ÔHIS COULD BE EASILY CORRECTED BY SETTING THE Ð0 AND Ð1 LINES TO OUTPUT IN THE BEGINNING OF THE INTERFACING ROUTINE (300 - 312): ÌÄÁ $00 ÏÒÁ #$02 ÓÔÁ $00 O ÔHE PROGRAM DOES NOT RESTORE THE ORIGINAL STATE OF THE ÃÉÁ2 ÃONTROL ÒEGISTER Á OR ÉNTERRUPT ÃONTROL ÒEGISTER. ÉT MIGHT BE IMPOSSIBLE TO START USING THE ËERNAL'S ÒÓ-232 ROUTINES AFTER RUNNING THIS. O ÉF THE USER REDIRECTED OUTPUT TO CASSETTE OR ÒÓ-232, INTERRUPTS WOULD BE REQUIRED. ÈOWEVER, THEY ARE COMPLETELY DISABLED. O ÉF A NON-MASKABLE INTERRUPT OCCURS WHILE THE LOADER PART IS BEING EXECUTED, THE PROGRAM WILL SCREW UP. ÔHIS WILL HAPPEN ALSO IN THE MAIN PART, IF AN ÎÍÉ IS ISSUED AFTER DISABLING ÒÏÍS AND É/Ï IN $0134 BUT BEFORE EXCHANGING THE CONTENTS OF THE MEMORY PLACES $Ã016 AND $ÄÄ7Á. _ÆREEZER CARTRIDGES_ ÔHERE ARE MANY CARTRIDGES THAT LET YOU TO STOP ALMOST ANY PROGRAM FOR "BACK-UP" PURPOSES. ÏNE OF THE MOST POPULAR OF THESE FREEZER CARTRIDGES IS THE ÁCTION ÒEPLAY ÖÉ MADE BY ÄATEL ÅLECTRONICS BACK IN 1989. ÔHE CARTRIDGE HAS 8 KILOBYTES ÒÁÍ AND 32 KILOBYTES ÒÏÍ ON BOARD, AND IT HAS A CUSTOM CHIP FOR FIDDLING WITH THE Ã64 CARTRIDGE PORT LINES -ÅØÒÏÍ, -ÇÁÍÅ, -ÉÒÑ, -ÎÍÉ AND ÂÁ. ÉF THE -ÎÍÉ LINE IS NOT ASSERTED (THE ÎÍÉ INTERRUPTS ARE ENABLED), ALL FREEZER CARTRIDGES SHOULD BE ABLE TO HALT ANY PROGRAM. ×HEN THE USER PRESSES THE "FREEZE" BUTTON, THE CARTRIDGES HALT THE PROCESSOR BY DROPPING THE ÂÁ LINE LOW. ÔHEN THEY SWITCH SOME OF THEIR OWN ÒÏÍ TO THE $Å000 - $ÆÆÆÆ BLOCK BY SELECTING THE ÕLTIÍAX CONFIGURATION WITH THE -ÅØÒÏÍ AND -ÇÁÍÅ LINES. ÁFTER THIS, THEY ASSERT THE -ÎÍÉ LINE AND RELEASE THE ÂÁ LINE. ÁFTER COMPLETING THE CURRENT INSTRUCTION, THE PROCESSOR WILL TAKE THE ÎÍÉ INTERRUPT AND LOAD THE PROGRAM COUNTER FROM THE VECTOR AT $ÆÆÆÁ, PROVIDED THAT THE ÎÍÉ LINE WAS NOT ASSERTED ALREADY. ÔHIS APPROACH IS PRONE TO MANY FLAWS. ÆIRSTLY, IF THE PROCESSOR IS EXECUTING A WRITE INSTRUCTION WHEN THE PROGRAM IS BEING HALTED, AND IF THE WRITE OCCURRED OUTSIDE THE AREA $0000 - $0ÆÆÆ, THE DATA WOULD GET LOST, IF THE ÕLTIÍAX CONFIGURATION WAS ASSERTED TOO EARLY. ÔHIS CAN BE CORRECTED TO SOME EXTENT BY WAITING AT LEAST TWO CYCLES AFTER ASSERTING THE ÂÁ LINE, AS THE PROCESSOR WILL NOT STOP DURING WRITE CYCLES. ÈOWEVER, THIS IS OF NO HELP IF THE PROCESSOR HAS NOT GOTTEN TO THE WRITE STAGE YET. ÓECONDLY, IF THE INSTRUCTION BEING EXECUTED IS OUTSIDE THE AREA $0000 - $0ÆÆÆ, OR IF IT ACCESSES ANY DATA OUTSIDE THAT AREA, THE PROCESSOR WILL FETCH EITHER WRONG PARAMETERS OR INCORRECT DATA, OR BOTH. ÉF THE INSTRUCTION DOES NOT WRITE ANYTHING, WILL ONLY CORRUPT ONE PROCESSOR REGISTER. ÔHIRDLY, IF THE ÎÍÉ INTERRUPTS ARE DISABLED, PRESSING THE "FREEZE" BUTTON DOES NOT HAVE ANY OTHER IMMEDIATE EFFECT THAN LEAVING THE ÕLTIÍAX MODE ASSERTED, WHICH MAKES ANY SYSTEM ÒÁÍ OUTSIDE THE AREA $0000 - $0ÆÆÆ UNAVAILABLE. ÉT ALSO FORCES THE É/Ï AREA ($Ä000 - $ÄÆÆÆ) ON. ÉF THE PROGRAM HAS ANY INSTRUCTIONS OR DATA OUTSIDE THE LOWMOST FOUR KILOBYTES, IT WILL EVENTUALLY JAM, AS THAT DATA WILL BE SOMETHING ELSE THAN THE PROGRAM EXPECTS. ÏNE MIGHT EXCEPT THAT READING FROM OPEN ADDRESS SPACE SHOULD RETURN RANDOM BYTES. ÂUT, IN AT LEAST TWO Ã64'S, THE BYTES READ ARE MOSTLY $ÂÄ, WHICH IS THE OPCODE FOR ÌÄÁ ABSOLUTE,Ø. ÓO, IF THE PROCESSOR HAS A "GOOD LUCK", IT WILL HAPPILY EXECUTE ONLY ÌÄÁ $ÂÄÂÄ,Ø COMMANDS, AND IT MIGHT SURVIVE TO THE CARTRIDGE ÒÏÍ AREA WITHOUT JAMMING. ÏR IT COULD EVENTUALLY FETCH A ÂÒË AND JUMP TO THE CARTRIDGE ÒÏÍ VIA THE ÉÒÑ/ÂÒË VECTOR AT $ÆÆÆÅ. ÔHE ÁCTION ÒEPLAY ÖÉ HAS THE FAMILIAR AUTOSTART DATA IN THE BEGINNING OF BOTH THE ÒÏÍÌ AND ÒÏÍÈ BLOCKS BY DEFAULT, AND THAT DATA COULD BE INTERPRETED AS SENSIBLE COMMANDS. ÔHE ÁCTION ÒEPLAY ÖÉ WAS INDEED ABLE TO FREEZE MY TEST PROGRAM, EVEN THOUGH É HAD COVERED ITS -ÒÅÓÅÔ, -ÉÒÑ AND -ÎÍÉ LINES WITH A PIECE OF TAPE, UNTIL É RELOCATED THE PROGRAM TO THE FIRST 4 KILOBYTE BLOCK. _ÂUILDING AN UNBEATABLE FREEZER CIRCUIT_ ÁS YOU CAN SEE, IT IS TOTALLY IMPOSSIBLE TO DESIGN A FREEZER CARTRIDGE THAT FREEZES ANY PROGRAM. ÉF THE PROGRAM TO BE FREEZED HAS DISABLED THE ÎÍÉ INTERRUPTS, AND IF ITS CODE RUNS MOSTLY AT $0000 - $0ÆÆÆ OR $Ä000 - $ÄÆÆÆ, THE COMPUTER WILL MORE PROBABLY HANG THAN SUCCEED IN FREEZING THE PROGRAM. ÈOWEVER, IT IS POSSIBLE TO MAKE SOME INTERNAL MODIFICATIONS TO A Ã64, SO THAT IT CAN FREEZE LITERALLY ANY PROGRAM. ÙOU NEED TO EXPAND YOUR MACHINE TO 256 KILOBYTES FOLLOWING THE DOCUMENTS ON FTP.FUNET.FI IN THE /PUB/CBM/HARDWARE/256K DIRECTORY. ÉT WILL LET YOU TO RESET THE COMPUTER SO THAT ALL OF THE 64 KILOBYTES THE PREVIOUS PROGRAM USED, WILL REMAIN INTACT. ÉF YOU ADD A SWITCH TO ONE OF THE MEMORY EXPANSION CONTROLLER'S CHIP SELECTION LINES, THE PROGRAM BEING EXAMINED WILL HAVE NO WAY TO SCREW THE MACHINE UP, AS THE ADDITIONAL MEMORY MANAGEMENT REGISTERS WILL NOT BE AVAILABLE. Á FEW ENHANCEMENTS TO THIS CIRCUIT ARE REQUIRED SO THAT YOU CAN FREEZE THE PROGRAMS WITHOUT LOSING THE STATE OF THE É/Ï CHIPS. ÙOU WILL ALSO NEED TO REPLACE THE ËERNAL ÒÏÍ CHIP WITH YOUR OWN CODE, IF YOU DO NOT WANT TO LOSE THE STATE OF THE Á, Ø, Ð AND Ó REGISTERS. ÕNFORTUNATELY THIS CIRCUIT WILL NOT PRESERVE THE STATE OF THE PROCESSOR'S ÐERIPHERAL LINES (ITS BUILT-IN É/Ï PORT MAPPED TO THE MEMORY ADDRESSES 0 AND 1), NOR DOES IT RECORD THE PROGRAM COUNTER (ÐÃ). É HAVE A PARTIAL SOLUTION TO THE Ðà PROBLEM, THOUGH. ÉF YOU ARE INTERESTED IN THIS PROJECT, CONTACT ME. É WILL DESIGN THE ADDITIONAL HARDWARE, AND É WILL PROGRAM THE STARTUP ROUTINES, BUT É CERTAINLY DO NOT HAVE THE TIME TO PROGRAM ALL OF THE FREEZER SOFTWARE. ÍOST OF THE FREEZER SOFTWARE COULD BE IN ÒÁÍ, SO IT WOULD BE VERY EASY TO DEVELOP IT, AND YOU COULD EVEN USE EXISTING TOOLS BY PATCHING THEM SLIGHTLY. ============================================================================= ÆÌÄ - ÓCROLLING THE SCREEN BY ÍAREK ËLAMPAR (KLAMPAR@ELF.STUBA.SK) ÓCROLLING THE SCREEN -------------------- [INSPIRATED BY ÐASI ÏJALA ARTICLE 'ÏPENING THE BORDERS' FROM ISSUE#6] ÆROM ÐASI 'ÁLBERT' ÏJALA'S (PO87553@CS.TUT.FI OR ALBERT@CC.TUT.FI) ARTICLE: _ÓCROLLING THE SCREEN_ ÖÉà BEGINS TO DRAW THE SCREEN FROM THE FIRST BAD LINE. ÖÉà WILL KNOW WHAT LINE IS A BAD LINE BY COMPARING ITS SCAN LINE COUNTER TO THE VERTICAL SCROLL REGISTER : WHEN THEY MATCH, THE NEXT LINE IS A BAD LINE. ÉF WE CHANGE THE VERTICAL SCROLL REGISTER ($D011), THE FIRST BAD LINE WILL MOVE ALSO. ÉF WE DO THIS ON EVERY LINE, THE LINE COUNTER IN ÖÉà WILL NEVER MATCH WITH IT AND THE DRAWING NEVER STARTS (UNTIL IT IS ALLOWED TO DO SO). ×HEN WE DON'T HAVE TO WORRY ABOUT BAD LINES, WE HAVE ENOUGH TIME TO OPEN THE BORDERS AND DO SOME OTHER EFFECTS TOO. ÉT IS NOT NECASSARY TO CHANGE THE VERTICAL SCROLL ON EVERY LINE TO GET RID OF THE BAD LINES, JUST MAKE SURE THAT IT NEVER MATCHES THE LINE COUNTER (OR ACTUALLY THE LEAST SIGNIFICANT 3 BITS). ÙOU CAN EVEN SCROLL THE BAD LINES INDEPENDENTLY AND YOU HAVE ÆÌÄ - ÆLEXIBLE ÌINE ÄISTANCE. ÙOU JUST ALLOW A BAD LINE WHEN IT IS TIME TO DISPLAY THE NEXT CHARACTER ROW. ×ITH THIS YOU CAN BOUNCE THE LINES OR SCROLL A HIRES PICTURE VERY FAST DOWN THE SCREEN. (*** END OF ÁLBERT'S PARAGRAPH ***) ×ELL, EVERYTHING IMPORTANT WAS WRITTEN. É'M JUST ADDING THIS: ÆOR MOVING HIRES PICTURE REPLACE ÏÒÁ #$10 BY ÏÒÁ #$30. ÆOR ANOTHER ÆØ TRY TO REPLACE PART OF IRQ ROUTINE BEGINING WITH ÏÒÁ #$10 BY: ÏÒÁ #$Ã0 ÓÔÁ $Ä016, REMOVE ÊÓÒ ÃÈÏÆÓ, REPLACE ÌÄØ ÏÆÓÅÔ BY ÌÄØ #$FF AND ENJOY =) ÔHE DEMONSTARTION PROGRAM FOR ÆÌÄ APPLICATION ;--------------------------------------- ; ÃOMMODORE ÃRACKER 1993 ;--------------------------------------- ÆÒÏÍ = $32 ÔÏ = $ÆÁ ;--------------------------------------- *= $Ã000 ;--------------------------------------- ÉÎÉÔ ÌÄÁ #0 ÓÔÁ ÄÉÒ ; ÄIRECTION ÌÄÁ #$ÆÆ ; ÓET GARBAGE ÓÔÁ $3ÆÆÆ ÌÄÁ #ÆÒÏÍ ÓÔÁ ÏÆÓÅÔ ; ÓET OFSET ÓÅÉ ; ÄISABLE INTERRUPT ÌÄÁ #$7Æ ; ÄISABLE TIMER INTERRUPT ÓÔÁ $ÄÃ0Ä ÌÄÁ #1 ; ÅNABLE RASTER INTERRUPT ÓÔÁ $Ä01Á ÌÄÁ #<ÉÒÑ ; ÓET IRQ VECTOR ÓÔÁ $0314 ÌÄÁ #>ÉÒÑ ÓÔÁ $0315 ÌÄÁ #0 ; ÔO EVOKE OUR IRQ ROUTINE ON 0TH LINE ÓÔÁ $Ä012 ÃÌÉ ; ÅNABLE INTERRUPT ÒÔÓ ;--------------------------------------- ÉÒÑ ÌÄØ ÏÆÓÅÔ Ì2 ÌÄÙ $Ä012 ; ÍOVING 1ST BAD LINE Ì1 ÃÐÙ $Ä012 ÂÅÑ Ì1 ; ×AIT FOR BEGIN OF NEXT LINE ÄÅÙ ; ÉÙ - BAD LINE ÔÙÁ ÁÎÄ #$07 ; ÃLEAR HIGHER 5 BITS ÏÒÁ #$10 ; ÓET TEXT MODE ÓÔÁ $Ä011 ÄÅØ ÂÎÅ Ì2 ÉÎà $Ä019 ; ÁCKNOWLEDGE THE RASTER INTERRUPT ÊÓÒ ÃÈÏÆÓ ÊÍÐ $ÅÁ31 ; ÄO STANDARD IRQ ROUTINE ;--------------------------------------- ÏÆÓÅÔ .ÂÙÔÅ ÆÒÏÍ ÄÉÒ .ÂÙÔÅ 0 ;--------------------------------------- ÃÈÏÆÓ ÌÄÁ ÄÉÒ ; ÃHANGE ÏÆÓÅÔ OF SCREEN ÂÎÅ ÕÐ ÉÎà ÏÆÓÅÔ ; ÄOWN ÌÄÁ ÏÆÓÅÔ ÃÍÐ #ÔÏ ÂÎÅ ÓËÉÐ ÓÔÁ ÄÉÒ ÓËÉÐ ÒÔÓ ;--------------------------------------- ÕÐ ÄÅà ÏÆÓÅÔ ; ÕP ÌÄÁ ÏÆÓÅÔ ÃÍÐ #ÆÒÏÍ ÂÎÅ ÓËÉÐ ÌÄÁ #0 ÓÔÁ ÄÉÒ ÒÔÓ ============================================================================= ÔECH-TECH - MORE RESOLUTION TO VERTICAL SHIFT. BY ÐASI 'ÁLBERT' ÏJALA (PO87553@CS.TUT.FI _OR_ ALBERT@CC.TUT.FI) ×RITTEN ON 16-ÍAY-91 ÔRANSLATION 02-ÊUN-92 (ÁLL TIMINGS ARE IN ÐÁÌ, PRINCIPLES WILL APPLY TO ÎÔÓà TOO) ÏNE TIME HALF OF THE DEMOS HAD PICTURES WAVING HORIZONTALLY ON THE WIDTH OF THE WHOLE SCREEN. ÔHIS EFFECT IS NAMED TECH-TECH, AND THE AUDIENCE WAS PUZZLED. ÙOU CAN MOVE THE SCREEN ONLY EIGHT PIXELS USING THE HORIZONTAL SCROLL REGISTER. ÔHIS EFFECT WAS DONE USING CHARACTER GRAPHICS. ÈOW EXACTLY AND IS THE SAME POSSIBLE WITH SPRITES ? ÈORIZONTAL SCROLL REGISTER CAN MOVE THE SCREEN BY EIGHT PIXELS. ÔHIS ISN'T EVEN NEARLY ENOUGH TO PRODUCE A REALLY STUNNING EFFECT. ÙOU HAVE TO MOVE THE GRAPHICS ITSELF, FORTUNATELY WITH A RESOLUTION OF ONE CHARACTER POSITION (ONE BYTE) ONLY, THE REST CAN BE DONE WITH THE SCROLL REGISTER. ÄURING ONE SCAN LINE THERE IS NO TIME TO MOVE THE ACTUAL DATA, YOU CAN ONLY MOVE A POINTER. ÃHANGING THE VIDEO MATRIX POINTER WON'T HELP, BECAUSE ÖÉà (VIDEO INTERFACE CONTROLLER) WILL FETCH THE CHARACTER CODES ONLY AT CERTAIN TIMES, CALLED BAD LINES. ÙOU CAN CHANGE THE CHARACTER SET POINTER INSTEAD, BECAUSE ÖÉà READS THE DATA IT DISPLAYS DIRECTLY FROM THE CHARACTER SET MEMORY. ÃHARACTER SET-IMPLEMENTATION HAS ITS RESTRICTIONS ÂECAUSE HORIZONTAL MOVEMENT IS DONE BY CHANGING THE CHARACTER SETS, THE PICTURE OR TEXT MUST BE PURE GRAPHIC AND THE CHARACTER CODES IN THE VIDEO MATRIX MUST BE IN A NUMERICAL ORDER. ÔHE NORMAL PICTURE IS IN THE FIRST CHARACTER MEMORY AND IN THE NEXT ONE IT IS SHIFTED ONE CHARACTER POSITION TO THE RIGHT. ÏNE VIDEO BANK CAN HOLD ONLY SEVEN FULL CHARACTER MEMORIES BESIDES THE VIDEO MATRIX. ÔHIS LIMITS THE MOVEMENT OF THE PICTURE TO 56 PIXELS. ÉT IS POSSIBLE TO GET MORE MOVEMENT IF YOU USE SMALLER PICTURE OR ANOTHER VIDEO BANK. ÔHE SHIFT IS DONE SO THAT ON EACH SCAN LINE WE UPDATE THE HORIZONTAL SCROLL REGISTER ($Ä016) WITH THE THREE LOWEST BITS OF THE SHIFT VALUE. ×E USE THE OTHER BITS TO SELECT THE RIGHT CHARACTER SET ($Ä018). ÉN A TECH-TECH THE SHIFT VALUE CHANGES DURING THE DISPLAY OF THE WHOLE PICTURE, AND THE VALUES ARE STORED IN A TABLE. ÉN ADDITION TO THAT, THE SHIFT VALUES SHOULD BE PUT INTO TWO TABLES, ONE FOR THE HORIZONTAL SCROLL REGISTER AND ANOTHER FOR THE CHARACTER SET SELECT. ÔHIS IS NECESSARY, BECAUSE THERE IS NO TIME FOR EXTRA CALCULATIONS ON A BAD LINE. ÂECAUSE WE HAVE TO CHANGE THE CHARACTER SET AND X-SCROLL DYNAMICALLY, WE ALSO NEED A RASTER ROUTINE TO SHOW A TECH-TECH. Á RASTER ROUTINE IS A ROUTINE WHICH IS SYNCHRONIZED TO THE ELECTRON BEAM. ÔHIS EATS UP THE PROCESSOR TIME: THE BIGGER THE PICTURE, THE LESS TIME IS LEFT OVER FOR OTHER ACTIVITIES. ÏN OTHER THAN BAD LINES YOU CAN DO OTHER FUNNY THINGS, LIKE CHANGE THE COLOR OF THE BACKGROUND OR BORDER. ÁN EXAMPLE PROGRAM ÔHE DEMO PROGRAM USES VIDEO BANK 2, MEMORY ADDESSES $4000-7FFF. ÔHE VIDEO MATRIX IS IN THE BEGINNING OF THE BANK. ÏNLY INVERTED CHARS ARE USED FOR THE GRAPHICS, THIS WAY WE HAVE ALL EIGHT CHARACTER MEMORIES AVAILABLE AND THE MAXIMUM SHIFT IS 64 PIXELS. ÔHE AREA FOR THE TECH-TECH IN THE VIDEO MATRIX IS EIGHT CHARACTER ROWS HIGH, BUT IT HAS IDENTICAL GRAPHICS ON EVERY LINE. ÔHIS IS WHY WE USE ONLY 320 BYTES FROM EACH CHARACTER SET. ÙOU CAN USE A JOYSTICK TO CONTROL THE MOVEMENT OF THE TECH-TECH. ÔHE STICK DECREASES OR INCREASES THE SHIFT ADD VALUE IN A RESOLUTION OF A HALF PIXEL. ×HEN THE SHIFT REACHES ITS HIGHEST/LOWEST VALUE, THE DIRECTION OF THE ADD IS REVERSED. ÊUST EXPERIMENT WITH IT.